package com.dmxtechnologies.community.war.handler;

import java.io.IOException;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedList;

import javax.faces.FacesException;
import javax.faces.context.ExceptionHandler;
import javax.faces.context.FacesContext;
import javax.faces.event.AbortProcessingException;
import javax.faces.event.ExceptionQueuedEvent;
import javax.faces.event.ExceptionQueuedEventContext;
import javax.faces.event.SystemEvent;
import javax.servlet.http.HttpServletResponse;

public class CMSExceptionHandler extends ExceptionHandler {

	private LinkedList<ExceptionQueuedEvent> unhandledExceptions;

	private LinkedList<ExceptionQueuedEvent> handledExceptions;

	private ExceptionQueuedEvent handled;

	private boolean errorPagePresent;

	public CMSExceptionHandler() {
		this.errorPagePresent = true;
	}

	public CMSExceptionHandler(boolean errorPagePresent) {
		this.errorPagePresent = errorPagePresent;
	}

	@Override
	public ExceptionQueuedEvent getHandledExceptionQueuedEvent() {
		return handled;
	}

	@Override
	public Iterable<ExceptionQueuedEvent> getHandledExceptionQueuedEvents() {
		return ((handledExceptions != null)? handledExceptions : Collections.<ExceptionQueuedEvent> emptyList());
	}

	@Override
	public Throwable getRootCause(Throwable t) {
		return t;
	}

	@Override
	public Iterable<ExceptionQueuedEvent> getUnhandledExceptionQueuedEvents() {
		return ((unhandledExceptions != null)? unhandledExceptions : Collections.<ExceptionQueuedEvent> emptyList());
	}

	// 关键在此方法，这里是做异常处理的
	@Override
	public void handle() throws FacesException {
		for (Iterator<ExceptionQueuedEvent> i = getUnhandledExceptionQueuedEvents().iterator(); i.hasNext();) {
			ExceptionQueuedEvent event = i.next();
			ExceptionQueuedEventContext context = (ExceptionQueuedEventContext) event
					.getSource();
			Throwable t = context.getException();
			if (t instanceof RuntimeException) {
				FacesContext fc = FacesContext.getCurrentInstance();
				// 此处做了一个导航，倒转到错误页面，在错误页面中显示错误信息
				try {
					// NavigationHandler nav =
					// fc.getApplication().getNavigationHandler();
					// nav.handleNavigation(fc, null, "/faces/error.xhtml");
				 	// fc.renderResponse();
					HttpServletResponse response = (HttpServletResponse) fc
							.getExternalContext().getResponse();
					String url = fc.getExternalContext()
							.getRequestContextPath() + "/faces/error.xhtml";
					response.sendRedirect(url);
					fc.renderResponse();
				} catch (IOException e) {
					e.printStackTrace();
				} finally {
					i.remove();
				}
			}
		}
	}

	@Override
	public boolean isListenerForSource(Object source) {
		return (source instanceof ExceptionQueuedEventContext);
	}

	@Override
	public void processEvent(SystemEvent event) throws AbortProcessingException {
		if (event != null) {
			if (unhandledExceptions == null) {
				unhandledExceptions = new LinkedList<ExceptionQueuedEvent>();
			}
			unhandledExceptions.add((ExceptionQueuedEvent) event);
		}
	}
}
